package comment;

/**
 * 
 * @author Qu huanwen
 * Awesome coding skills. -- Seabook
 *
 */
public class Comment {

	public static void main(String[] args) {
		Comment c = new Comment();

		String[] code0 = new String[] { "public class Comment{",

		" public String[] strip(String[] code){", "//this isn't right!",
				"  return code;", " }", "}" };
		printCode(c.strip(code0));

		String[] code1 = new String[] { "/*public class Comment{",

		" public String[] strip(String[] code){", "//this isn't right!",
				"  return code;", " }", "}*/" };
		printCode(c.strip(code1));

		String[] code2 = new String[] { "String s = \"\\\"/**/\\\"\"" };
		printCode(c.strip(code2));

		String[] code3 = new String[] { "public class Comment{",

		" public String[] strip(String[] code){", " //this isn't right!",
				"  return code;", " }", "}" };
		printCode(c.strip(code3));

		String[] code4 = new String[] { "char c = '\"'//\"" };
		printCode(c.strip(code4));

		String[] code5 = new String[] { "public class Comment{",

		" public String[] strip(String[] code){", " //this isn't right!",
				"  return /*test*/code;", "/*remove*/", " }", "}" };
		printCode(c.strip(code5));
	}

	static void printCode(String[] code) {
		System.out.println("==============================");
		for (String l : code) {
			System.out.println(l);
		}
	}

	private static final int FREE = 1;
	private static final int LINE_COMMENT = 2;
	private static final int BLOCK_COMMENT = 3;
	private static final int QUOTED = 4;

	public String[] strip(String[] code) {
		StringBuffer codeBuf = new StringBuffer("\n"); // add a line break in
														// the head for
														// startOfLine
		for (String s : code) {
			codeBuf.append(s);
			codeBuf.append("\n");
		}
		StringBuffer result = new StringBuffer();
		String rest = codeBuf.toString();

		int status = FREE;
		boolean startOfLine = true;
		String[] breaked;

		whileLoop: while (true) {
			switch (status) {
			case FREE:
				breaked = breakBy(rest, new String[] { "//", "\"", "/*" },
						false);
				result.append(breaked[0]);
				startOfLine = breaked[0].endsWith("\n");
				rest = breaked[1];
				if (rest.startsWith("//"))
					status = LINE_COMMENT;
				else if (rest.startsWith("/*"))
					status = BLOCK_COMMENT;
				else if (rest.startsWith("\""))
					status = QUOTED;
				else
					break whileLoop;
				break;
			case LINE_COMMENT:
				rest = rest.substring(2);
				breaked = breakBy(rest, new String[] { "\n" }, false);
				rest = breaked[1];
				if (rest.length() >= 1 && startOfLine) {
					rest = rest.substring(1);
				}
				startOfLine = true;
				status = FREE;
				break;
			case BLOCK_COMMENT:
				rest = rest.substring(2);
				breaked = breakBy(rest, new String[] { "*/" }, false);
				rest = breaked[1];
				if (rest.length() >= 2)
					rest = rest.substring(2);
				if (startOfLine && rest.startsWith("\n"))
					rest = rest.substring(1);
				status = FREE;
				break;
			case QUOTED:
				result.append("\"");
				rest = rest.substring(1);
				breaked = breakBy(rest, new String[] { "\"", "\n" }, true);
				result.append(breaked[0]);
				rest = breaked[1];
				startOfLine = rest.startsWith("\n");
				if (rest.length() >= 1) {
					result.append(rest.substring(0, 1));
					rest = rest.substring(1);
				}
				status = FREE;
				break;
			}
		}

		return result.substring(1).split("\n");
	}

	private String[] breakBy(String input, String[] seperators,
			boolean escapable) {
		int pos = 0;
		while (pos < input.length()) {
			if (input.charAt(pos) == '\\' && escapable) {
				pos += 2;
			} else if (startsWith(input, pos, seperators)) {
				break;
			} else {
				pos++;
			}
		}
		return new String[] { input.substring(0, pos), input.substring(pos) };
	}

	private boolean startsWith(String str, int offset, String[] ps) {
		for (String p : ps) {
			if (str.startsWith(p, offset))
				return true;
		}
		return false;
	}
}